/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
#include <string.h>
#include <jni.h>
#include <dlfcn.h>
#include <android/log.h>
#include <time.h>
#include "stdio.h"
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
/* This is a trivial JNI example where we use a native method
 * to return a new VM String. See the corresponding Java source
 * file located at:
 *
 *   apps/samples/hello-jni/project/src/com/example/hellojni/HelloJni.java
 */

typedef unsigned char byte;
typedef struct _STRUCT_CHAIN_DATA_INPUT {
	int iLen;
	byte* pcData;
	struct _STRUCT_CHAIN_DATA_INPUT* pNextNode;
} STRUCT_CHAIN_DATA_INPUT;

typedef struct _net_work_data {
	char* pKey;
	char* pValue;
	struct _net_work_data* pNext;
} net_work_data;

#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, "Test", __VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG  , "Test", __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO   , "Test", __VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN   , "Test", __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR  , "Test", __VA_ARGS__)

static JavaVM *g_jvm = NULL;
static jobject g_objInstense;
static void* handle = NULL; //Protocol.so句柄
static void* deviceInfoHandle = NULL; //读取设备信息SO文件的句柄
static byte *g_publicBuffer=NULL;
void check()
{

		const int bufsize = 1024;
		char filename[bufsize];
		char line[bufsize];
		int pid = getpid();
    //LOGD("------------------%d", pid);
    sprintf(filename, "/proc/%d/status", pid);
		FILE* fd = fopen(filename, "r");
		if (fd != NULL)
		{
			while (fgets(line, bufsize, fd))
			{
				if (strncmp(line, "TracerPid", 9) == 0)
				{
					int statue = atoi(&line[10]);

					//LOGD("------------------%s", line);
					if (statue != 0)
					{
						//LOGD("------------------be attached !! kill %d", pid);
						fclose(fd);
						int ret = kill(pid, SIGKILL);
					}
					break;
				}
			}
			fclose(fd);
		} else
		{
			//LOGD("------------------open %s fail...", filename);
		}
}
/**
 * 发送数据
 */
int sendMessage(byte* send, int nLen) {
	LOGE("sendMessage:%s,%d", (char*)send, nLen);
	int nResult = 0;
	JNIEnv *env;
	jclass cls;
	//Attach主线程
	if (g_jvm != NULL) {
		if ((*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL) != JNI_OK) {
			LOGE("%s: AttachCurrentThread() failed", __FUNCTION__);
			return 0;
		}
	}

	if (g_objInstense != NULL) {
		//找到对应的类
		cls = (*env)->GetObjectClass(env, g_objInstense);
		if (cls == NULL) {
			LOGE("FindClass() Error.....");
			return 0;
		}

		jmethodID jmethodSend = (*env)->GetMethodID(env, cls, "send", "([BI)I");
		LOGE("sendMessage:GetMethodID");
		if (jmethodSend != 0) {
			jbyteArray jarray = (*env)->NewByteArray(env, nLen);
			LOGE("sendMessage:NewByteArray");
			(*env)->SetByteArrayRegion(env, jarray, 0, nLen, (jbyte*) send);
			LOGE("sendMessage:SetByteArrayRegion");
			nResult = (*env)->CallIntMethod(env, g_objInstense, jmethodSend,
					jarray, nLen);
			LOGE("sendMessage:CallIntMethod");

			(*env)->DeleteLocalRef(env, jarray);
			LOGE("sendMessage:DeleteLocalRef-jarray");
		}

		(*env)->DeleteLocalRef(env, cls);
		LOGE("sendMessage:DeleteLocalRef-cls");

		//usleep(50000);
	}
	return nResult;
}

jstring charToJstring(JNIEnv *env, const char *pat) {
    jclass strClass = (*env)->FindClass(env, "java/lang/String");
    jmethodID ctorID = (*env)->GetMethodID(env, strClass, "<init>","([BLjava/lang/String;)V");
    jbyteArray bytes = (*env)->NewByteArray(env, strlen(pat));
    (*env)->SetByteArrayRegion(env, bytes, 0, strlen(pat), (jbyte *) pat);
    jstring encoding = (*env)->NewStringUTF(env, "utf-8");
    return (jstring) (*env)->NewObject(env, strClass, ctorID, bytes, encoding);
}

//jbyteArray getJByte(JNIEnv *env,byte* pIn){
//    int nLen=getArrayLen(pIn);
//    jbyteArray jarray = (*env)->NewByteArray(env, nLen);
//    LOGE("getJByte:NewByteArray");
//    (*env)->SetByteArrayRegion(env, jarray, 0, nLen, (jbyte*) pIn);
//    LOGE("getJByte:returnbyte");
//    return jarray;
//}
/**
 * 重汽刷写zip文件解压回调函数
 algorithm：算法名称；LA_ZQF_UNZIP
 	pIn：输入参数；两字节长度+文件路径
 	pOut：输出结果的指针，内存由protocol分配；
 	nLength：pOut内存的可用长度

 pOut返回结果：
 第一个表示成功失败（成功0，失败非0）+两字节长度+解压后的文件路径
 */
int localAlgorithm( const char *algorithm,const byte* pIn,byte *pOut,int nLength){
    	int nResult = 0;
    	JNIEnv *env;
    	jclass cls;
    	//Attach主线程
    	if (g_jvm != NULL) {
    		if ((*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL) != JNI_OK) {
    			LOGE("%s: AttachCurrentThread() failed", __FUNCTION__);
    			return 0;
    		}
    	}

    	if (g_objInstense != 0) {
    		//找到对应的类
    		cls = (*env)->GetObjectClass(env, g_objInstense);
    		if (cls == NULL) {
    			LOGE("FindClass() Error.....");
    			return 0;
    		}
    		jmethodID jmethodRecv = (*env)->GetMethodID(env, cls, "LocalAlgorithm", "(Ljava/lang/String;[BI)[B");
    		LOGE("LocalAlgorithm:algorithm=,%s",algorithm);
    		LOGE("LocalAlgorithm:GetMethodID");
    		if (jmethodRecv != 0) {
    		    //转换数据
    		    jstring js=charToJstring(env,algorithm);

    		    int len=0;
    		    if(strcmp(algorithm,"CALL_NETDECRYPT")==0){
                    len=strlen(pIn);
    		    }else if(strcmp(algorithm,"NETDECRYPT_DO_RSULT")==0){
//                    len=strlen(pIn);
                }else{
                    len=pIn[0]*256+pIn[1]+2;
                }

                //转换数据
                //int len=pIn[0]*256+pIn[1]+2;

//                int len=strlen(pIn);


                LOGE("LocalAlgorithm:pinLen=,%d",len);
                jbyteArray jarrayIn=(*env)->NewByteArray(env, len);
                LOGE("LocalAlgorithm:NewByteArray");
                (*env)->SetByteArrayRegion(env, jarrayIn, 0, len, (jbyte*) pIn);
                LOGE("LocalAlgorithm:SetByteArrayRegion");

    			jbyteArray jarray = (jbyteArray)(*env)->CallObjectMethod(env,
    					g_objInstense,jmethodRecv,js,jarrayIn,nLength);
    			(*env)->DeleteLocalRef(env, jarrayIn);
    			LOGE("LocalAlgorithm:CallMethod");
    			if (jarray != NULL) {
    				jsize length = (*env)->GetArrayLength(env, jarray);
    				LOGE("LocalAlgorithm:GetArrayLength,%d", length);
    				if (length > 0) {
    					jbyte* arrayBody = (jbyte*) (*env)->GetByteArrayElements(
    							env, jarray, JNI_FALSE);
    					LOGE("LocalAlgorithm:GetByteArrayElement");
    					//					recv = (byte*)arrayBody;
    					memcpy(pOut, (byte*) arrayBody, length);
    					nResult = 1;
    					//(*env)-> ReleaseByteArrayElements(env, jarray,(jbyte *)arrayBody, JNI_COMMIT);
    					(*env)->ReleaseByteArrayElements(env, jarray,
    							(jbyte *) arrayBody, 0);

    					LOGE("LocalAlgorithm:ReleaseByteArrayElements");
    				}

    			}
    			(*env)->DeleteLocalRef(env, jarray);
    			/*
    			 * 小心最后一个参数,如果为0是会释放 m 所指向的内存的. 如果M刚好指向一个栈上的数组的话,
    			 * 这样可能在Release 版本中造成内存方面的随机错误.可以用JNI_COMMIT来避免.
    			 */
    		}
    		(*env)->DeleteLocalRef(env, cls);
    		LOGE("LocalAlgorithm:DeleteLocalRef-cls");
    	}
    	return nResult;
}


/**
 * 接收数据
 */
int recvMessage(byte* recv, int nLen, int nTimeOut) {
	LOGE("recvMessage:%d,%d", nLen, nTimeOut);
	int nResult = 0;
	JNIEnv *env;
	jclass cls;
	//Attach主线程
	if (g_jvm != NULL) {
		if ((*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL) != JNI_OK) {
			LOGE("%s: AttachCurrentThread() failed", __FUNCTION__);
			return 0;
		}
	}

	if (g_objInstense != 0) {
		//找到对应的类
		cls = (*env)->GetObjectClass(env, g_objInstense);
		if (cls == NULL) {
			LOGE("FindClass() Error.....");
			return 0;
		}
		jmethodID jmethodRecv = (*env)->GetMethodID(env, cls, "recv", "(II)[B");
		LOGE("recvMessage:GetMethodID");
		if (jmethodRecv != 0) {
			//			jbyteArray jarray = (*env)->NewByteArray(env,nLen);
			jbyteArray jarray = (jbyteArray)(*env)->CallObjectMethod(env,
					g_objInstense, jmethodRecv, nLen, nTimeOut);
			LOGE("recvMessage:CallMethod");
			if (jarray != NULL) {
				jsize length = (*env)->GetArrayLength(env, jarray);
				LOGE("recvMessage:GetArrayLength,%d", length);
				if (length > 0) {
					jbyte* arrayBody = (jbyte*) (*env)->GetByteArrayElements(
							env, jarray, JNI_FALSE);
					LOGE("recvMessage:GetByteArrayElement");
					//					recv = (byte*)arrayBody;
					memcpy(recv, (byte*) arrayBody, nLen);
					//					LOGE("recvMessage:%x,%x,%x",recv[0]);
					nResult = 1;
					//(*env)-> ReleaseByteArrayElements(env, jarray,(jbyte *)arrayBody, JNI_COMMIT);
					(*env)->ReleaseByteArrayElements(env, jarray,
							(jbyte *) arrayBody, 0);

					LOGE("recvMessage:ReleaseByteArrayElements");
				}

			}
			(*env)->DeleteLocalRef(env, jarray);
			/*
			 * 小心最后一个参数,如果为0是会释放 m 所指向的内存的. 如果M刚好指向一个栈上的数组的话,
			 * 这样可能在Release 版本中造成内存方面的随机错误.可以用JNI_COMMIT来避免.
			 */
		}
		(*env)->DeleteLocalRef(env, cls);
		LOGE("recvMessage:DeleteLocalRef-cls");
	}
	return nResult;
}

/**
 * 接收数据
 */
int recvMessageAll(byte* recv, int nLen, int nTimeOut) {
	LOGE("recvMessageAll:%d,%d", nLen, nTimeOut);
	int nResult = 0;
	JNIEnv *env;
	jclass cls;
	//Attach主线程
	if (g_jvm != NULL) {
		if ((*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL) != JNI_OK) {
			LOGE("%s: AttachCurrentThread() failed", __FUNCTION__);
			return 0;
		}
	}

	if (g_objInstense != 0) {
		//找到对应的类
		cls = (*env)->GetObjectClass(env, g_objInstense);
		if (cls == NULL) {
			LOGE("FindClass() Error.....");
			return 0;
		}
		jmethodID jmethodRecv = (*env)->GetMethodID(env, cls, "recvAll", "(II)[B");
		LOGE("recvMessageAll:GetMethodID");
		if (jmethodRecv != 0) {
			//			jbyteArray jarray = (*env)->NewByteArray(env,nLen);
			jbyteArray jarray = (jbyteArray)(*env)->CallObjectMethod(env,
					g_objInstense, jmethodRecv, nLen, nTimeOut);
			LOGE("recvMessageAll:CallMethod");
			if (jarray != NULL) {
				jsize length = (*env)->GetArrayLength(env, jarray);
				LOGE("recvMessageAll:GetArrayLength,%d", length);
				if (length > 0) {
					jbyte* arrayBody = (jbyte*) (*env)->GetByteArrayElements(
							env, jarray, JNI_FALSE);
					LOGE("recvMessageAll:GetByteArrayElement");
					//					recv = (byte*)arrayBody;
					memcpy(recv, (byte*) arrayBody, nLen);
					//					LOGE("recvMessage:%x,%x,%x",recv[0]);
					nResult = 1;
					//(*env)-> ReleaseByteArrayElements(env, jarray,(jbyte *)arrayBody, JNI_COMMIT);
					(*env)->ReleaseByteArrayElements(env, jarray,
							(jbyte *) arrayBody, 0);
					LOGE("recvMessageAll:ReleaseByteArrayElements");
				}

			}
			(*env)->DeleteLocalRef(env, jarray);
			/*
			 * 小心最后一个参数,如果为0是会释放 m 所指向的内存的. 如果M刚好指向一个栈上的数组的话,
			 * 这样可能在Release 版本中造成内存方面的随机错误.可以用JNI_COMMIT来避免.
			 */
		}
		(*env)->DeleteLocalRef(env, cls);
		LOGE("recvMessageAll:DeleteLocalRef-cls");
	}
	return nResult;
}
/**
 * 超时
 */
void timeDelay(int ntime) {
	/*LOGE("timeDelay:%d",time);
	 int nResult = 0;
	 JNIEnv *env;
	 jclass cls;
	 //Attach主线程
	 if( g_jvm != NULL ){
	 if((*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL) != JNI_OK)
	 {
	 LOGE("%s: AttachCurrentThread() failed", __FUNCTION__);
	 return 0;
	 }
	 }

	 if( g_objInstense != 0 )
	 {
	 //找到对应的类
	 cls = (*env)->GetObjectClass(env,g_objInstense);
	 if(cls == NULL)
	 {
	 LOGE("FindClass() Error.....");
	 return 0;
	 }
	 jmethodID jmethodTime = (*env)->GetMethodID(env,cls, "timeDelay", "(I)V");
	 LOGE("timeDelay:GetMethodID");
	 if( jmethodTime != 0 )
	 {
	 //			jbyteArray jarray = (*env)->NewByteArray(env,nLen);
	 (jbyteArray)(*env)->CallObjectMethod(env,g_objInstense, jmethodTime,time);
	 LOGE("timeDelay:CallMethod");


	 * 小心最后一个参数,如果为0是会释放 m 所指向的内存的. 如果M刚好指向一个栈上的数组的话,
	 * 这样可能在Release 版本中造成内存方面的随机错误.可以用JNI_COMMIT来避免.

	 }
	 else{
	 LOGE("timeDelay:GetMethodID is null");
	 }
	 (*env)->DeleteLocalRef( env, cls );
	 LOGE("timeDelay:DeleteLocalRef-cls");
	 }*/

	/*struct time t;
	 gettime(&t);
	 long start = t.ti_hund;
	 int nRun = 1;
	 while(nRun){
	 gettime(&t);
	 long end = t.ti_hund;
	 if( (end - start) >= ntime ){
	 break;
	 }
	 }*/
	/*int nIndex = ntime;
	 while( nIndex > 0 ){
	 usleep(1000);
	 nIndex --;
	 }*/
	usleep(ntime * 1000);
	return;
}


void SetIdleThreadState(jboolean blRun,int nDelayTime_ms){
	LOGE("SetIdleThreadState:%d,%d", blRun,nDelayTime_ms);
	int nResult = 0;
	JNIEnv *env;
	jclass cls;
	if (g_jvm != NULL) {
		if ((*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL) != JNI_OK) {
			LOGE("%s: AttachCurrentThread() failed", __FUNCTION__);
			return 0;
		}
	}

	if (g_objInstense != NULL) {
		cls = (*env)->GetObjectClass(env, g_objInstense);
		if (cls == NULL) {
			LOGE("FindClass() Error.....");
			return 0;
		}
		jmethodID jmethodSend = (*env)->GetMethodID(env, cls, "SetIdleThreadState",
													"(ZI)V");
		LOGE("SetIdleThreadState:GetMethodID");
		if (jmethodSend != 0) {
			(*env)->CallVoidMethod(env, g_objInstense, jmethodSend,blRun,nDelayTime_ms);
			LOGE("SetIdleThreadState:CallIntMethod");
		}
		(*env)->DeleteLocalRef(env, cls);
		LOGE("SetIdleThreadState:DeleteLocalRef-cls");
		//usleep(50000);
	}
	return nResult;

}

//protocol调用服务器算法相关
void SendDecryptData(byte* send, int nLen, int allLen){
	LOGE("sendMessage:%s,%d", (char*)send, nLen);
	int nResult = 0;
	JNIEnv *env;
	jclass cls;
	//Attach主线程
	if (g_jvm != NULL) {
		if ((*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL) != JNI_OK) {
			LOGE("%s: AttachCurrentThread() failed", __FUNCTION__);
			return 0;
		}
	}

	if (g_objInstense != NULL) {
		//找到对应的类
		cls = (*env)->GetObjectClass(env, g_objInstense);
		if (cls == NULL) {
			LOGE("FindClass() Error.....");
			return 0;
		}

		jmethodID jmethodSend = (*env)->GetMethodID(env, cls, "sendDecryptData", "([BII)I");
		LOGE("sendMessage:GetMethodID");
		if (jmethodSend != 0) {
            jbyteArray jarray = (*env)->NewByteArray(env, nLen);
			LOGE("sendMessage:NewByteArray");
			(*env)->SetByteArrayRegion(env, jarray, 0, nLen, (jbyte*) send);
			LOGE("sendMessage:SetByteArrayRegion");
			nResult = (*env)->CallIntMethod(env, g_objInstense, jmethodSend,
					jarray, nLen, allLen);
			LOGE("sendMessage:CallIntMethod");

			(*env)->DeleteLocalRef(env, jarray);
			LOGE("sendMessage:DeleteLocalRef-jarray");
		}

		(*env)->DeleteLocalRef(env, cls);
		LOGE("sendMessage:DeleteLocalRef-cls");
	}
	return nResult;
}


void PrintLogCallback(const byte* tag,const int taglen,const byte* logtext, const int textlen){
	LOGE("PrintLogCallback:%s,%s", tag,logtext);
	int nResult = 0;
	JNIEnv *env;
	jclass cls;
	if (g_jvm != NULL) {
		if ((*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL) != JNI_OK) {
			LOGE("%s: AttachCurrentThread() failed", __FUNCTION__);
			return 0;
		}
	}

	if (g_objInstense != NULL) {
		cls = (*env)->GetObjectClass(env, g_objInstense);
		if (cls == NULL) {
			LOGE("FindClass() Error.....");
			return 0;
		}
		jmethodID jmethodSend = (*env)->GetMethodID(env, cls, "print_log",
													"([B[B)V");
		LOGE("PrintLogCallback:GetMethodID");
		if (jmethodSend != 0) {

            jbyteArray tagjarray = (*env)->NewByteArray(env, taglen);
            LOGE("PrintLogCallback:NewByteArray");
            (*env)->SetByteArrayRegion(env, tagjarray, 0, taglen, (jbyte*) tag);
            LOGE("PrintLogCallback:SetByteArrayRegion");


            jbyteArray textjarray = (*env)->NewByteArray(env, textlen);
            LOGE("PrintLogCallback:NewByteArray");
            (*env)->SetByteArrayRegion(env, textjarray, 0, textlen, (jbyte*) logtext);
            LOGE("PrintLogCallback:SetByteArrayRegion");

			(*env)->CallVoidMethod(env, g_objInstense, jmethodSend,tagjarray,textjarray);
			LOGE("PrintLogCallback:CallIntMethod");
		}
		(*env)->DeleteLocalRef(env, cls);
		LOGE("PrintLogCallback:DeleteLocalRef-cls");
		//usleep(50000);
	}
	return nResult;
}

void NoticeClientCallback(const byte* tag,const int taglen,const byte* logtext, const int textlen){
	LOGE("NoticeClientCallback:%s,%s", tag,logtext);
	int nResult = 0;
	JNIEnv *env;
	jclass cls;
	if (g_jvm != NULL) {
		if ((*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL) != JNI_OK) {
			LOGE("%s: AttachCurrentThread() failed", __FUNCTION__);
			return 0;
		}
	}

	if (g_objInstense != NULL) {
		cls = (*env)->GetObjectClass(env, g_objInstense);
		if (cls == NULL) {
			LOGE("FindClass() Error.....");
			return 0;
		}
		jmethodID jmethodSend = (*env)->GetMethodID(env, cls, "notice_client",
													"([B[B)V");
		LOGE("NoticeClientCallback:GetMethodID");
		if (jmethodSend != 0) {

            jbyteArray tagjarray = (*env)->NewByteArray(env, taglen);
            LOGE("NoticeClientCallback:NewByteArray");
            (*env)->SetByteArrayRegion(env, tagjarray, 0, taglen, (jbyte*) tag);
            LOGE("NoticeClientCallback:SetByteArrayRegion");


            jbyteArray textjarray = (*env)->NewByteArray(env, textlen);
            LOGE("NoticeClientCallback:NewByteArray");
            (*env)->SetByteArrayRegion(env, textjarray, 0, textlen, (jbyte*) logtext);
            LOGE("NoticeClientCallback:SetByteArrayRegion");

			(*env)->CallVoidMethod(env, g_objInstense, jmethodSend,tagjarray,textjarray);
			LOGE("NoticeClientCallback:CallIntMethod");
		}
		(*env)->DeleteLocalRef(env, cls);
		LOGE("NoticeClientCallback:DeleteLocalRef-cls");
		//usleep(50000);
	}
	return nResult;
}


int updateUI(int nType, byte* pOutData, int nLen) {
	LOGE("updateUI:%d,%s,%d", nType, (char*)pOutData, nLen);
	int nResult = 0;
	JNIEnv *env;
	jclass cls;
	if (g_jvm != NULL) {
		if ((*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL) != JNI_OK) {
			LOGE("%s: AttachCurrentThread() failed", __FUNCTION__);
			return 0;
		}
	}

	if (g_objInstense != NULL) {
		cls = (*env)->GetObjectClass(env, g_objInstense);
		if (cls == NULL) {
			LOGE("FindClass() Error.....");
			return 0;
		}
		jmethodID jmethodSend = (*env)->GetMethodID(env, cls, "updateUI",
				"(I[BI)I");
		LOGE("updateUI:GetMethodID");
		if (jmethodSend != 0) {
			jbyteArray jarray = (*env)->NewByteArray(env, nLen);
			LOGE("updateUI:NewByteArray");
			(*env)->SetByteArrayRegion(env, jarray, 0, nLen, (jbyte*) pOutData);
			LOGE("updateUI:SetByteArrayRegion");
			nResult = (*env)->CallIntMethod(env, g_objInstense, jmethodSend,
					nType, jarray, nLen);
			LOGE("updateUI:CallIntMethod");
			(*env)->DeleteLocalRef(env, jarray);
			LOGE("updateUI:DeleteLocalRef-jarray");
		}
		(*env)->DeleteLocalRef(env, cls);
		LOGE("updateUI:DeleteLocalRef-cls");
		//usleep(50000);
	}
	return nResult;
}
void ClearRecvDataPool() {

	LOGE("ClearRecvDataPool");
	JNIEnv *env;
	jclass cls;
	if (g_jvm != NULL) {
		if ((*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL) != JNI_OK) {
			LOGE("%s: AttachCurrentThread() failed", __FUNCTION__);
			return;
		}
	}

	if (g_objInstense != NULL) {
		cls = (*env)->GetObjectClass(env, g_objInstense);
		if (cls == NULL) {
			LOGE("FindClass() Error.....");
			return;
		}
		jmethodID jmethodSend = (*env)->GetMethodID(env, cls,
				"ClearRecvDataPool", "()V");
		LOGE("ClearRecvDataPool:GetMethodID");
		if (jmethodSend != 0) {
			(*env)->CallVoidMethod(env, g_objInstense, jmethodSend);
			LOGE("ClearRecvDataPool:CallIntMethod");
		}
		(*env)->DeleteLocalRef(env, cls);
		LOGE("ClearRecvDataPool:DeleteLocalRef-cls");
		usleep(50000);
	}
}

/*
 * 读取防盗密码
 * pList 输入参数，链表
 * pResult 输出参数
 */
void net_work_communication(net_work_data* pList, byte* pResult) {
	//得到链表头结点
	net_work_data* pTemp = pList;

	LOGE("net_work_communication");
	JNIEnv *env;
	jclass cls;
	if (g_jvm != NULL) {
		if ((*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL) != JNI_OK) {
			LOGE("%s: AttachCurrentThread() failed", __FUNCTION__);
			return;
		}
	}

	if (g_objInstense != NULL) {
		cls = (*env)->GetObjectClass(env, g_objInstense);
		if (cls == NULL) {
			LOGE("FindClass() Error.....");
			return;
		}

		jmethodID jmethodGet = (*env)->GetMethodID(env, cls, "getAntiTheftPass",
				"(Ljava/util/HashMap;)[B");
		LOGE("net_work_communication:GetMethodID");
		if (jmethodGet != 0) {
			LOGE("net_work_communication:new hash map");

			// new一个hashmap对象
			jclass class_hashmap = (*env)->FindClass(env, "java/util/HashMap");
			jmethodID hashmap_construct_method = (*env)->GetMethodID(env,
					class_hashmap, "<init>", "()V");
			jobject obj_hashmap = (*env)->NewObject(env, class_hashmap,
					hashmap_construct_method);
			jmethodID hashmap_put_method = (*env)->GetMethodID(env,
					class_hashmap, "put",
					"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
			LOGE("net_work_communication:new hash map complete");

			//获取链表数据，封装到map里面
			while (pTemp != NULL) {
				LOGE(
						"net_work_communication:%s  %s", pTemp->pKey, pTemp->pValue);

				(*env)->CallObjectMethod(env, obj_hashmap, hashmap_put_method,
						(*env)->NewStringUTF(env, pTemp->pKey),
						(*env)->NewStringUTF(env, pTemp->pValue));
				//(*env)->CallObjectMethod(env,g_objInstense,hashmap_put_method,
				//(byte*)"aaaa", (byte*)"bbbb");

				pTemp = pTemp->pNext;
			}
			LOGE("net_work_communication:hash map put data complete");

			//调用读取密码接口
			LOGE("net_work_communication:CallMethod");

			jbyteArray jarray = (jbyteArray)(*env)->CallObjectMethod(env,
					g_objInstense, jmethodGet, obj_hashmap);

			if (jarray != NULL) {
				jsize length = (*env)->GetArrayLength(env, jarray);
				LOGE("net_work_communication:GetArrayLength,%d", length);
				if (length > 0) {
					jbyte* arrayBody = (jbyte*) (*env)->GetByteArrayElements(
							env, jarray, JNI_FALSE);
					LOGE("net_work_communication:GetByteArrayElement");
					memcpy(pResult, (byte*) arrayBody, length);
					(*env)->ReleaseByteArrayElements(env, jarray,
							(jbyte *) arrayBody, 0);
					LOGE("net_work_communication:ReleaseByteArrayElements");
				}

			}
			(*env)->DeleteLocalRef(env, jarray);
			(*env)->DeleteLocalRef(env, obj_hashmap);
		}

		(*env)->DeleteLocalRef(env, cls);
		LOGE("net_work_communication:DeleteLocalRef-cls");
	}
}

/**
 * 注册回调函数
 */
void registerCallBack(void* handle) {
	if (handle != NULL) {
		void (*registSend)(void*);
		void (*registRecv)(void*);
		void (*registRecvAll)(void*);
		void (*registTimeDelay)(void*);
		void (*registUpdateUI)(void*);
		void (*registClearDataPool)(void*);
		void (*registNetWorkCommunication)(void*);
		void (*SetIdleThread)(void*);
		void (*registerPrintlLog)(void*);
		void (*registerNoticeClient)(void*);
		void (*RegistSendDecryptCallback)(void*);
		void (*RegistLocalAlgorithmCallback)(void*);


        RegistSendDecryptCallback= (void (*)(void*)) dlsym(handle,
        											   "RegistSendDecryptCallback");
        		if (RegistSendDecryptCallback == NULL) {
        			LOGE("RegistSendDecryptCallback:Error:%s,", dlerror());
        		} else {
        			RegistSendDecryptCallback(SendDecryptData);
        		}

		registerPrintlLog= (void (*)(void*)) dlsym(handle,
											   "regist_print_log_callback");
		if (registerPrintlLog == NULL) {
			LOGE("registerPrintlLog:Error:%s,", dlerror());
		} else {
			registerPrintlLog(PrintLogCallback);
		}

		registerNoticeClient= (void (*)(void*)) dlsym(handle,
        											   "registerNoticeClient");
        		if (registerNoticeClient == NULL) {
        			LOGE("registerNoticeClient:Error:%s,", dlerror());
        		} else {
        			registerNoticeClient(NoticeClientCallback);
        		}


		SetIdleThread= (void (*)(void*)) dlsym(handle,
											   "regist_Set_IdleThread_State");
		if (SetIdleThread == NULL) {
			LOGE("SetIdleThreadState:Error:%s,", dlerror());
		} else {
			SetIdleThread(SetIdleThreadState);
		}

		registSend = (void (*)(void*)) dlsym(handle,
				"regist_send_cmd_callback");
		if (registSend == NULL) {
			LOGE("resgistSend:Error:%s,", dlerror());
			return;
		}

		RegistLocalAlgorithmCallback = (void (*)(void*)) dlsym(handle,
				"RegistLocalAlgorithmCallback");
		if (RegistLocalAlgorithmCallback == NULL) {
			LOGE("RegistLocalAlgorithmCallback:Error:%s,", dlerror());
		}else{
			RegistLocalAlgorithmCallback(localAlgorithm);
			LOGE("RegistLocalAlgorithmCallback:success");
		}

		registRecv = (void (*)(void*)) dlsym(handle,
				"regist_receive_cmd_callback");
		if (registRecv == NULL) {
			LOGE("registRecv:Error:%s,", dlerror());
		}else{
			registRecv(recvMessage);
		}
		registRecvAll = (void (*)(void*)) dlsym(handle,
				"regist_receive_all_cmd_callback");
		if (registRecvAll == NULL) {
			LOGE("registRecvAll:Error:%s,", dlerror());
		} else {
			registRecvAll(recvMessageAll);
		}

		registTimeDelay = (void (*)(void*)) dlsym(handle, "regist_time_delay");
		if (registTimeDelay == NULL) {
			LOGE("registTimeDelay:Error:%s,", dlerror());
			return;
		}
		registUpdateUI = (void (*)(void*)) dlsym(handle,
				"regist_update_ui_callback");
		if (registUpdateUI == NULL) {
			LOGE("registUpdateUI:Error:%s,", dlerror());
		} else {
			registUpdateUI(updateUI);
		}
		registClearDataPool = (void (*)(void*)) dlsym(handle,
				"regist_clear_recv_data_pool_callback");
		if (registClearDataPool == NULL) {
			LOGE("registClearDataPool:Error:%s,", dlerror());
		} else {
			registClearDataPool(ClearRecvDataPool);
		}

		registNetWorkCommunication = (void (*)(void*)) dlsym(handle,
				"regist_net_work_communication");
		if (registNetWorkCommunication == NULL) {
			LOGE("registNetWorkCommunication:Error:%s,", dlerror());
		} else {
			registNetWorkCommunication(net_work_communication);
		}
		registSend(sendMessage);
		registTimeDelay(timeDelay);
	}
}

void* loadSO(JNIEnv* env, jobject thiz, jobject objMain, jstring jLibPath) {
	int jres = 0;
	void* soHandle = NULL;

	//保存全局JVM以便在子线程中使用
	if (g_jvm == NULL) {
		(*env)->GetJavaVM(env, &g_jvm);
	}

	//不能直接赋值(g_obj = obj)
	if (g_objInstense == NULL) {
		g_objInstense = (*env)->NewGlobalRef(env, objMain);
	}

	//jclass clsMain = (*env)->FindClass(env, "com/jpt/mds/activity/MainActivity" );
	// 实例化类对象
	//g_objInstense = getInstance(env, g_clsObject);

	const char* szLibPath = (*env)->GetStringUTFChars(env, jLibPath, 0);
	LOGE("SOFilePath:%s", szLibPath);

	soHandle = dlopen(szLibPath, RTLD_LAZY);

	registerCallBack(soHandle);

	(*env)->ReleaseStringUTFChars(env, jLibPath, szLibPath);
	LOGE("registerCallBack");

	return soHandle;
}

/**
 * 实例化类对象
 */
jobject getInstance(JNIEnv *env, jclass clazz) {
	// 获取构造方法
	jmethodID constructor = (*env)->GetMethodID(env, clazz, "<init>", "()V");
	if (NULL == constructor) {
		return NULL;
	}
	// 实例化类对象
	return (*env)->NewObject(env, clazz, constructor);
}

int JNICALL Java_com_yx_corelib_core_ProtocolJNI_registerCallBack(JNIEnv* env,jobject thiz,jobject objMain,jstring jLibPath)
{
	handle = loadSO(env,thiz,objMain,jLibPath);
	if (handle==NULL)
	{
		LOGE("dlopenError:handle==null");
return 0;
	}
//	int jres = 0;
//	//保存全局JVM以便在子线程中使用
//	if(g_jvm == NULL){
//		(*env)->GetJavaVM(env,&g_jvm);
//	}
//
//	//不能直接赋值(g_obj = obj)
//	if(g_objInstense == NULL){
//		g_objInstense = (*env)->NewGlobalRef(env,objMain);
//	}
//
//	//jclass clsMain = (*env)->FindClass(env, "com/jpt/mds/activity/MainActivity" );
//	// 实例化类对象
//	//g_objInstense = getInstance(env, g_clsObject);
//
//	const char* szLibPath = (*env)->GetStringUTFChars(env, jLibPath, 0);
//	LOGE("SOFilePath:%s",szLibPath);
//
//	handle=dlopen(szLibPath,RTLD_LAZY);
//
//	if (handle==NULL)
//	{
//		LOGE("dlopenError:handle==null");
//		exit(-1);
//	}
//
//	registerCallBack(handle);
//
//	(*env)->ReleaseStringUTFChars(env, jLibPath, szLibPath);
//	LOGE("registerCallBack");
	return 0;
}

void JNICALL Java_com_yx_corelib_core_ProtocolJNI_unRegister(JNIEnv* env,jobject thiz) {

	if(handle != NULL){
		LOGE("unregister");
dlclose(handle);
handle = NULL;
}
}

void JNICALL Java_com_yx_corelib_core_ProtocolJNI_destroyCallBack(JNIEnv* env,jobject thiz) {

    if( g_objInstense != NULL ) {
        (*env)->DeleteGlobalRef(env,g_objInstense);
        g_objInstense = NULL;
    }

    if( g_jvm != NULL ) {
        (*g_jvm)->DetachCurrentThread(g_jvm);
        g_jvm = NULL;
    }
}

int callInterface(void* soHandle, JNIEnv* env, jobject thiz,
jstring strFunction, jbyteArray szInput, jobject szOutput) {
int nResult = 0;
jbyteArray jOutput;
jclass clazz_output;
jmethodID id_output;
    check();
LOGE("Step0:begin");
const char* szFunction = (*env)->GetStringUTFChars(env, strFunction, 0);
LOGE("Step1:Function:%s", szFunction);

if (soHandle == NULL) {
LOGE("Step2:", "handle == NULL");
return nResult;
}
int (*fun)(void*, void*);
fun = (int (*)(void*, void*)) dlsym(soHandle, szFunction);
if (fun == NULL) {
LOGE("Step3:Error:%s,", dlerror());
return nResult;
}

clazz_output = (*env)->GetObjectClass(env, szOutput);

jbyte* inputBuf = (jbyte*) (*env)->GetByteArrayElements(env, szInput, NULL);
LOGE("Step4:InputBuf:%s", (const char*)inputBuf);

 //输出参数
 //	jmethodID outputInit = (*env)->GetMethodID(env,clazz_output, "<init>", "()V");
 //	if (NULL == outputInit) {
 //		return 0;
 //	}
 //	// 实例化类对象
 //	jobject jOutObject = (*env)->NewObject(env,clazz_output, outputInit);

 //重新组装链表

STRUCT_CHAIN_DATA_INPUT* pInputData = (STRUCT_CHAIN_DATA_INPUT*) malloc(
	sizeof(STRUCT_CHAIN_DATA_INPUT));
if (pInputData == NULL) {
LOGE("Step5:pInputData is NULL");
return nResult;
}
pInputData->pcData = NULL;
pInputData->pNextNode = NULL;
STRUCT_CHAIN_DATA_INPUT* pCurrentData = NULL;
int nPos = 0;
int nCount = 0;
int i, n, m;
 //int a = 0;//ddd
byte* btArray = (byte*) inputBuf;
LOGE("Step6:InputArray:%s", (const char*)btArray);

nCount = btArray[0] & 0xFF;
nCount |= ((btArray[1] << 8) & 0xFF00);
nCount |= ((btArray[2] << 16) & 0xFF0000);
nCount |= ((btArray[3] << 24) & 0xFF000000);

nPos += 4;
LOGE("Step7:nCount:%d", nCount);

for (n = 0; n < nCount; n++) {

char* szData = NULL;
int nLen = 0;
nLen = btArray[nPos] & 0xFF;
nLen |= ((btArray[nPos + 1] << 8) & 0xFF00);
nLen |= ((btArray[nPos + 2] << 16) & 0xFF0000);
nLen |= ((btArray[nPos + 3] << 24) & 0xFF000000);
LOGE(
		"nLen:%d,%d,%d,%d,%d", nLen, btArray[nPos], btArray[nPos + 1], btArray[nPos + 2], btArray[nPos + 3]);
nPos += 4;

szData = (char*) malloc(nLen);
memcpy(szData, btArray + nPos, nLen);

//LOGE("----data begin------");
//for(a = 0; a < nLen; a++){
//	LOGE("%02X",szData[a]);
//}
//LOGE("----data end------");

LOGE("szData:%c,%d", szData[0], nPos);
nPos += nLen;
LOGE("malloc:%d", nLen);
if (n == 0 && pInputData != NULL) {
	pInputData->iLen = (nLen == 0 ? 0 : nLen - 1);
	pInputData->pcData = szData;

	pCurrentData = pInputData;
	LOGE("pCurrentData=pInputData%d", n);
} else if (n > 0 && n < nCount && pCurrentData != NULL) {
	STRUCT_CHAIN_DATA_INPUT* pTmp = (STRUCT_CHAIN_DATA_INPUT*) malloc(
			sizeof(STRUCT_CHAIN_DATA_INPUT));
	pTmp->iLen = (nLen == 0 ? 0 : nLen - 1);
	pTmp->pcData = szData;
	pTmp->pNextNode = NULL;

	pCurrentData->pNextNode = pTmp;
	pCurrentData = pTmp;
	LOGE("pCurrentData=pTmp%d", n);
}
}

LOGE("Step8:InputComplete");
byte* btOutput = (byte*) malloc(10240);
memset(btOutput, 0, 10240);
LOGE("malloc:InputComplete");
 //调用函数
nResult = (*fun)(pInputData, btOutput);
LOGE("Step9:Output:%s", (char*)btOutput);
 //byte数组转
jOutput = (*env)->NewByteArray(env, 10240);
(*env)->SetByteArrayRegion(env, jOutput, 0, 10240, (jbyte*) btOutput);
LOGE("Step10:SetByteArrayRegion");
jfieldID id_field = (*env)->GetFieldID(env, clazz_output, "byteArray", "[B");
(*env)->SetObjectField(env, szOutput, id_field, jOutput);
LOGE("Step11:OutputComplete");
 //释放缓存
free(btOutput);
LOGE("Step12:freeOutPut");

(*env)->DeleteLocalRef(env, jOutput);
LOGE("Step13:DeleteLocalRef-jOutput");

(*env)->ReleaseByteArrayElements(env, szInput, (jbyte *) inputBuf, 0);
inputBuf = NULL;
LOGE("Step14:DeleteLocalRef-inputBuf");

(*env)->DeleteLocalRef(env, clazz_output);
LOGE("Step15:DeleteLocalRef-clazz_output");
 //释放链表
pCurrentData = pInputData;
while (pCurrentData != NULL) {
STRUCT_CHAIN_DATA_INPUT* pTmp = pCurrentData->pNextNode;
LOGE("Delete1");
if (pCurrentData->pcData != NULL) {
	LOGE("Delete2");
	free(pCurrentData->pcData);
	pCurrentData->pcData = NULL;
}
LOGE("Delete3:%d", (int)pCurrentData);
free(pCurrentData);
LOGE("FreeParent");
pCurrentData = pTmp;
}
pInputData = NULL;
(*env)->ReleaseStringUTFChars(env, strFunction, szFunction);
szFunction = NULL;
LOGE("Step16:FreeComplete");
}

jint
JNICALL Java_com_yx_corelib_core_ProtocolJNI_callInterface(JNIEnv* env,
jobject thiz, jstring strFunction, jbyteArray szInput, jobject szOutput) {

return callInterface(handle, env, thiz, strFunction, szInput, szOutput);
}

int callInitPublicBuffer(void* soHandle, JNIEnv* env, jobject thiz,
                         jstring strFunction) {
	check();
	const char* szFunction = (*env)->GetStringUTFChars(env, strFunction, 0);
	if (soHandle == NULL) {
		LOGE("Step111111:", "handle == NULL");
		return 0;
	}
	void (*fun)(void*);
	fun = (void (*)(void*)) dlsym(soHandle, szFunction);
	if (fun == NULL) {
		LOGE("Step123333333:Error:%s,", dlerror());
		return 0;
	}

	if (g_publicBuffer==NULL)
	{
		g_publicBuffer = malloc(10240);
        LOGE("Step22222222222");
	}
	if (g_publicBuffer)
	{
		fun(g_publicBuffer);
        LOGE("Step333333333333333");
 	}
	return 1;
}

jint
JNICALL Java_com_yx_corelib_core_ProtocolJNI_callInitPublicBuffer(JNIEnv* env,
														   jobject thiz, jstring strFunction){
	return callInitPublicBuffer(handle, env, thiz, strFunction);
}
jint
JNICALL Java_com_yx_corelib_core_ProtocolJNI_initProtocolConfig(JNIEnv* env,
jobject thiz, jstring strFunction, jint type, jbyteArray szInput) {
int nResult = 0;
int nType = type;
const char* szFunction = (*env)->GetStringUTFChars(env, strFunction, 0);
LOGE("Step1:Function:%s,type:%d", szFunction, type);

if (handle == NULL) {
LOGE("Step2:", "handle == NULL");
return nResult;
}
int (*fun)(int, void*);
fun = (int (*)(int, void*)) dlsym(handle, szFunction);
if (fun == NULL) {
LOGE("Step3:Error:%s,", dlerror());
return nResult;
}

jbyte* inputBuf = (jbyte*) (*env)->GetByteArrayElements(env, szInput, NULL);
LOGE("Step4:InputBuf:%s", (const char*)inputBuf);

 //输出参数
 //	jmethodID outputInit = (*env)->GetMethodID(env,clazz_output, "<init>", "()V");
 //	if (NULL == outputInit) {
 //		return 0;
 //	}
 //	// 实例化类对象
 //	jobject jOutObject = (*env)->NewObject(env,clazz_output, outputInit);

 //重新组装链表
STRUCT_CHAIN_DATA_INPUT* pInputData = (STRUCT_CHAIN_DATA_INPUT*) malloc(
	sizeof(STRUCT_CHAIN_DATA_INPUT));
pInputData->pcData = NULL;
pInputData->pNextNode = NULL;
STRUCT_CHAIN_DATA_INPUT* pCurrentData = NULL;
int nPos = 0;
int nCount = 0;
int i, n, m;
byte* btArray = (byte*) inputBuf;
LOGE("Step6:InputArray:%s", (const char*)btArray);

nCount = btArray[0] & 0xFF;
nCount |= ((btArray[1] << 8) & 0xFF00);
nCount |= ((btArray[2] << 16) & 0xFF0000);
nCount |= ((btArray[3] << 24) & 0xFF000000);

nPos += 4;
LOGE("Step7:nCount:%d", nCount);

for (n = 0; n < nCount; n++) {

char* szData = NULL;
int nLen = 0;
nLen = btArray[nPos] & 0xFF;
nLen |= ((btArray[nPos + 1] << 8) & 0xFF00);
nLen |= ((btArray[nPos + 2] << 16) & 0xFF0000);
nLen |= ((btArray[nPos + 3] << 24) & 0xFF000000);
LOGE(
		"nLen:%d,%d,%d,%d,%d", nLen, btArray[nPos], btArray[nPos + 1], btArray[nPos + 2], btArray[nPos + 3]);
nPos += 4;

szData = (char*) malloc(nLen + 1);
memset(szData, 0, nLen + 1);
memcpy(szData, btArray + nPos, nLen);
LOGE("szData:%c,%d", szData[0], nPos);
nPos += nLen;
LOGE("malloc:%d", n);
if (n == 0 && pInputData != NULL) {
	pInputData->iLen = nLen;
	pInputData->pcData = szData;

	pCurrentData = pInputData;
	LOGE("pCurrentData=pInputData%d", n);
} else if (n > 0 && n < nCount && pCurrentData != NULL) {
	STRUCT_CHAIN_DATA_INPUT* pTmp = (STRUCT_CHAIN_DATA_INPUT*) malloc(
			sizeof(STRUCT_CHAIN_DATA_INPUT));
	pTmp->iLen = nLen;
	pTmp->pcData = szData;
	pTmp->pNextNode = NULL;

	pCurrentData->pNextNode = pTmp;
	pCurrentData = pTmp;
	LOGE("pCurrentData %d", pTmp);
}
}

LOGE("Step8:InputComplete");
 //调用函数
nResult = (*fun)(nType, pInputData);
LOGE("Step9:Output:%d", nResult);
 //byte数组转
 //释放缓存

(*env)->ReleaseByteArrayElements(env, szInput, (jbyte *) inputBuf, 0);
inputBuf = NULL;
LOGE("Step10:DeleteLocalRef-inputBuf");

 //释放链表
STRUCT_CHAIN_DATA_INPUT* pTemp = pInputData;
while (pTemp != NULL) {
LOGE("Delete0");
LOGE("pTemp %d", pTemp);
STRUCT_CHAIN_DATA_INPUT* pTemp1 = (STRUCT_CHAIN_DATA_INPUT*) pTemp->pNextNode;
LOGE("pTemp nextNode %d", pTemp1);
LOGE("Delete1");
if (pTemp->pcData != NULL) {
	LOGE("Delete2");
	free(pTemp->pcData);
	pTemp->pcData = NULL;
}
LOGE("Delete3:%d", (int)pTemp);
free(pTemp);
LOGE("FreeParent");
pTemp = pTemp1;
}
pInputData = NULL;
(*env)->ReleaseStringUTFChars(env, strFunction, szFunction);
szFunction = NULL;
LOGE("Step12:FreeComplete");
return nResult;
}

int
JNICALL Java_com_yx_corelib_core_ProtocolJNI_registerDeviceInfoCallBack(
JNIEnv* env, jobject thiz, jobject objMain, jstring jLibPath) {
deviceInfoHandle = loadSO(env, thiz, objMain, jLibPath);
if (deviceInfoHandle == NULL) {
LOGE("dlopenError:handle==null");
return 0;
}
return 0;
}

void JNICALL Java_com_yx_corelib_core_ProtocolJNI_unRegisterDeviceInfo(JNIEnv* env,jobject thiz) {

	if(deviceInfoHandle != NULL){
		LOGE("unregister");
dlclose(deviceInfoHandle);
deviceInfoHandle = NULL;
}
}

jint
JNICALL Java_com_yx_corelib_core_ProtocolJNI_readDeviceInfo(JNIEnv* env,
jobject thiz, jstring strFunction, jbyteArray szInput, jobject szOutput) {
return callInterface(deviceInfoHandle, env, thiz, strFunction, szInput,
szOutput);
}
